import store from 'src/vuex/store';
import Toast from 'cube-ui/lib/toast';
import axios from 'axios';
import qs from 'qs';
import API_LIST from 'src/API_LIST';
import { formaturl } from 'src/utils/utils';

export default class InitData {
	constructor({
		openid_url, user_url, jssdk_url, upload_location_url, redirect_url, switch_lang,
	}) {
		this.openid_url = openid_url;
		this.user_url = user_url;
		this.jssdk_url = jssdk_url;
		this.upload_location_url = upload_location_url;
		this.redirect_url = redirect_url;

		this.debug = API_LIST.APP_DEBUG;

		this.lang = switch_lang || false;

		this.target_url = window.location.href.split('#').shift();

		this.url_info = formaturl() || {};

		store.commit('userInfo/setAppid', this.url_info.appid);
	}

	// 用来获取实例
	static getInstance(params) {
		if (!this.instance) {
			this.instance = new InitData(params);
		}
		return this.instance;
	}

	// 初始化数据
	init() {
		return this.handleOpenidRequest()
			.then((openid) => {
				if (!openid) return;
				this.url_info.openid = openid;

				return this.handleUserinfoRequest()
					.then(() => {
						if (API_LIST.APP_DEBUG || !this.jssdk_url) return;
						this.handleJssdkRequest();
					});
			});
	}

	// debug模式下的初始化数据
	debugInit() {
		return this.handleUserinfoRequest()
			.then(() => {
				if (API_LIST.APP_DEBUG || !this.jssdk_url) return;
				this.handleJssdkRequest();
			});
	}

	// 处理openid的请求
	handleOpenidRequest() {
		const query_str = qs.stringify({
			appid: this.url_info.appid,
			cache: 1,
		});

		return this.fetchOpenid(query_str)
			.then(({ data }) => {
				if (parseInt(data.code, 10) !== 0) throw new Error(data.error);

				return data.openid;
			})
			.catch(() => {
				const toast = Toast.$create({
					time: 2000,
					txt: '正在跳转授权...',
				});
				toast.show();

				this.redirectToOAuth();
			});
	}

	// 处理userinfo的请求
	handleUserinfoRequest() {
		const param = {
			openid: this.url_info.openid || store.state.userInfo.user_info.openid,
		};
		const app_id = this.url_info.appid;
		if (app_id) {
			param.appid = app_id;
		}

		const query_str = qs.stringify(param);

		return this.fetchUserInfo(query_str)
			.then(({ data }) => {
				if (parseInt(data.code, 10) !== 0) throw new Error(data.error);

				const { wechat_user } = data;

				store.commit('userInfo/setUserInfo', wechat_user);

				this.handleLangRequest(wechat_user);
			})
			.catch((err) => {
				const toast = Toast.$create({
					type: 'error',
					time: 2000,
					txt: err.message || err.statusText,
				});
				toast.show();
				return Promise.reject(err.message || err.statusText);
			});
	}

	/**
	 * 语言切换请求的处理
	 * @param  {Object} wechat_user {微信用户信息}
	 * @return {undefined}
	 */
	handleLangRequest(wechat_user) {
		// if (!this.lang || !this.url_info.lang) { store.commit('userInfo/initDataComplete'); return; }
		const system_lang = this.url_info.lang || navigator.language;

		const url_lang = qs.parse(window.location.search.substr(1));

		const lang_param = {
			id: wechat_user.id,
			lang: url_lang.lang || system_lang,
		};

		store.dispatch('lang/changeWechatUserLang', lang_param)
			.then(() => {
				store.commit('userInfo/initDataComplete');
			});
	}

	// 处理jssdk请求
	handleJssdkRequest() {
		const param = {
			target_url: this.target_url,
		};

		return this.fetchJssdk(param)
			.then(({ data }) => {
				if (Number(data.code) !== 0) throw new Error(data.error);

				const wx_config = data.config;

				if (!API_LIST.APP_DEBUG) {
					wx_config.debug = false;
				}

				if (!wx) return;

				wx.config(wx_config);

				const self = this;

				// 成功后调用微信获取地理位置接口
				wx.ready(() => {
					self.uploadLocation();
				});
			})
			.catch((err) => {
				const toast = Toast.$create({
					type: 'warn',
					time: 2000,
					txt: err.message || err.statusText,
				});
				toast.show();
			});
	}

	// 处理上传地理位置请求
	handleUploadLocation(latitude, longitude, openid) {
		const param = {
			appid: this.url_info.appid,
			openid: openid || this.url_info.openid,
			longitude: String(longitude),
			latitude: String(latitude),
		};

		this.saveUserLocation(param)
			.then(({ data }) => {
				if (Number(data.code) !== 0) throw new Error(data.error);
			})
			.catch((err) => {
				const toast = Toast.$create({
					type: 'warn',
					time: 2000,
					txt: err.message || err.statusText,
				});
				toast.show();
			});
	}

	// 重定向
	redirectToOAuth() {
		const this_page_url = encodeURIComponent(window.location.href);

		window.location.href = `${this.redirect_url}?appid=${this.url_info.appid}&redirect_url=${this_page_url}&scope=snsapi_userinfo`;
	}

	// 获取用户openid
	fetchOpenid(query_str) {
		return axios.get(`${this.openid_url}?${query_str}`);
	}

	// 获取用户信息
	fetchUserInfo(query_str) {
		return axios.get(`${this.user_url}?${query_str}`);
	}

	// 获取jssdk
	fetchJssdk(param) {
		return axios.post(`${this.jssdk_url}/${this.url_info.appid}`, param, {
			hideLoading: true,
		});
	}

	// 保存用户地理位置信息
	saveUserLocation(param) {
		return axios.patch(this.upload_location_url, param, {
			hideLoading: true,
		});
	}

	/**
     * 调用微信地理位置接口
     * @return {undefined}
     */
	uploadLocation() {
		const self = this;

		wx.getLocation({
			type: 'wgs84', // 默认为wgs84的gps坐标，如果要返回直接给openLocation用的火星坐标，可传入'gcj02'
			success(res) {
				const { latitude, longitude } = res; // 纬度，浮点数，范围为90 ~ -90,经度，浮点数，范围为180 ~ -180。速度，以米/每秒计，位置精度
				if (latitude && longitude) {
					self.handleUploadLocation(latitude, longitude);
				}
			},
		});
	}

	/**
	 * 无公众号微信获取地理位置
	 * @return {undefined}}
	 */
	getLocation(openid) {
		const self = this;
		if ('geolocation' in navigator) {
			navigator.geolocation.getCurrentPosition((position) => {
				self.handleUploadLocation(position.coords.latitude, position.coords.longitude, openid);
			});
		}
	}
}
